package com.softer.chengxin.excel.service.impl;

import com.softer.chengxin.common.domin.Common;
import com.softer.chengxin.common.domin.JsonResult;
import com.softer.chengxin.common.domin.ManagerPageResult;
import com.softer.chengxin.common.domin.Page;
import com.softer.chengxin.common.enums.InfoTypeEnum;
import com.softer.chengxin.common.enums.LevelEnum;
import com.softer.chengxin.common.enums.NumberEnum;
import com.softer.chengxin.common.enums.StatisticalReportEnum;
import com.softer.chengxin.common.util.DateFormatUtil;
import com.softer.chengxin.corp.dao.CorpDao;
import com.softer.chengxin.excel.dao.StatisticalReportDao;
import com.softer.chengxin.excel.domin.ExportExcel;
import com.softer.chengxin.excel.service.StatisticalReportService;
import com.softer.chengxin.scheduled.dao.ScheduledTaskDao;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Gong Zhiyang
 * @date 2019/2/20
 */
@Service
public class StatisticalReportServiceImpl implements StatisticalReportService {
    @Autowired
    private StatisticalReportDao statisticalReportDao;
    @Autowired
    private ExcelServiceImpl excelService;
    @Autowired
    private CorpDao corpDao;
    @Autowired
    private ScheduledTaskDao scheduledTaskDao;

    /**
     * 统计报表的导出
     *
     * @param exportExcel 统计报表查询实体
     * @param page        页面信息
     * @param loginName   登录名
     * @return 结果集
     */
    @Override
    public ManagerPageResult exportStatisticalReport(ExportExcel exportExcel, Page page, String loginName) {
        ManagerPageResult mpr = new ManagerPageResult();
        JsonResult jr = new JsonResult();
        List<Map<String, Object>> list = new ArrayList();
        Map<String, Object> map = new HashMap<>(16);
        String name;
        if (StringUtils.isNotBlank(exportExcel.getStreet())) {
            name = statisticalReportDao.getName(Integer.parseInt(exportExcel.getStreet()));
        } else if (exportExcel.getDistrict() != null) {
            name = statisticalReportDao.getName(exportExcel.getDistrict());
        } else {
            name = "合计";
        }
        map.put("name", name);
        String fields = exportExcel.getFields();
        excelService.commonOperation(exportExcel.getIsCX(), loginName, fields, NumberEnum.TWO_HUNDRED_AND_ONE.getNum(), exportExcel.getExcelName(), exportExcel.getExcelRecordId(), Common.ONE);
        String area = null;
        if (!Common.ADMIN.equals(loginName)) {
            area = corpDao.getDistinct(loginName);
        }

        if (StringUtils.isBlank(fields)) {
            commonResult(mpr, jr, list, Integer.parseInt(Common.ZERO));
            return mpr;
        }
        //1，获取企业数量
        getCorpNum(fields, area, exportExcel, map);
        //2，查询项目数量
        getProjectNum(fields, area, exportExcel, map);
        //3,通过三体系认证数量
        getThreeSystem(fields, area, exportExcel, map);
        //4,未通过三体系认证数量
        getNoThreeSystem(fields, area, exportExcel, map);
        //5,成立党支部数量
        getOrganization(fields, area, exportExcel, map);
        //6,未成立党支部数量
        getNoOrganization(fields, area, exportExcel, map);
        //7,收入
        getIncome(fields, area, exportExcel, map);
        //8,查询人数
        getPersonNum(fields, area, exportExcel, map);
        //9,查询各个等级的数量
        getLevelNum(fields, area, exportExcel, map);
        //10,查询黑名单数量
        getBlackListNum(fields, area, exportExcel, map);
        //11,查询项目各种面积,户数，居住人数
        getProjectArea(fields, area, exportExcel, map);
        //12,查询老旧小区，智能化管理小区，保障住房数量
        getHouseNum(fields, area, exportExcel, map);
        //13,业委会数量
        getProprietor(fields, area, exportExcel, map);
        //14,优良,负面信息数量
        getInfoNum(fields, area, exportExcel, map);
        //15,查询教育数量
        getTrainNum(fields, area, exportExcel, map);

        list.add(map);
        commonResult(mpr, jr, list, list.size());
        return mpr;
    }

    /**
     * 查询教育数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getTrainNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.MANAGE_TRAIN.getField())) {
            //项目经理培训数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, "subject_type", Common.ONE);
            map.put(StatisticalReportEnum.MANAGE_TRAIN.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.OTHER_TRAIN.getField())) {
            //其他培训数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, "subject_type", Common.TWO);
            map.put(StatisticalReportEnum.OTHER_TRAIN.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.CITY_DEPARTMENT.getField())) {
            //市级及以上物业主管部门培训数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, "department", Common.ONE);
            map.put(StatisticalReportEnum.CITY_DEPARTMENT.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.DISTRICT_DEPARTMENT.getField())) {
            //区（市）物业主管部门培训数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, "department", Common.TWO);
            map.put(StatisticalReportEnum.DISTRICT_DEPARTMENT.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.ASSOCIATION.getField())) {
            //国家、省、市物业协会培训数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, "department", String.valueOf(Common.THREE));
            map.put(StatisticalReportEnum.ASSOCIATION.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.ALL_TRAIN.getField())) {
            //培训总数量
            Integer num = statisticalReportDao.getTrainNum(area, exportExcel, null, null);
            map.put(StatisticalReportEnum.ALL_TRAIN.getField(), num);
        }
    }

    /**
     * 查询优良,负面信息数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getInfoNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.GOOD_INFO.getField())) {
            //优良信息数量
            Integer num = statisticalReportDao.getInfoNum(area, exportExcel, InfoTypeEnum.EXCELLENT.getCode());
            map.put(StatisticalReportEnum.GOOD_INFO.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.BAD_INFO.getField())) {
            //负面信息数量
            Integer num = statisticalReportDao.getInfoNum(area, exportExcel, InfoTypeEnum.NEGATIVE.getCode());
            map.put(StatisticalReportEnum.BAD_INFO.getField(), num);
        }
    }

    /**
     * 查询业委会数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getProprietor(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.PROPRIETOR.getField())) {
            //业委会数量
            Integer num = statisticalReportDao.getProprietor(area, exportExcel);
            map.put(StatisticalReportEnum.PROPRIETOR.getField(), num);
        }
    }

    /**
     * 查询老旧小区，智能化管理小区，保障住房数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getHouseNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.OLD_DISTRICT.getField())) {
            //老旧小区数量
            Integer num = statisticalReportDao.getHouseNum(area, exportExcel, StatisticalReportEnum.OLD_DISTRICT.getField());
            map.put(StatisticalReportEnum.OLD_DISTRICT.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.INTELLIGENT.getField())) {
            //智能化管理小区数量
            Integer num = statisticalReportDao.getHouseNum(area, exportExcel, StatisticalReportEnum.INTELLIGENT.getField());
            map.put(StatisticalReportEnum.INTELLIGENT.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.INDEMNIFICATORY.getField())) {
            //保障住房数量
            Integer num = statisticalReportDao.getHouseNum(area, exportExcel, StatisticalReportEnum.INDEMNIFICATORY.getField());
            map.put(StatisticalReportEnum.INDEMNIFICATORY.getField(), num);
        }
    }

    /**
     * 查询项目各种面积
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getProjectArea(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.PROJECT_ALL_AREA.getField())) {
            //项目总占地面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "project_area");
            map.put(StatisticalReportEnum.PROJECT_ALL_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.GROUND_AREA.getField())) {
            //地上建筑面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "building_land");
            map.put(StatisticalReportEnum.GROUND_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.UNDERGROUND_AREA.getField())) {
            //地下建筑面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "green_area");
            map.put(StatisticalReportEnum.UNDERGROUND_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.RESIDENTIAL_AREA.getField())) {
            //住宅建筑面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "public_facilities_area");
            map.put(StatisticalReportEnum.RESIDENTIAL_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.NON_RESIDENTIAL_AREA.getField())) {
            //非住宅建筑面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "other_area");
            map.put(StatisticalReportEnum.NON_RESIDENTIAL_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.GREEN_AREA.getField())) {
            //绿化面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "municipal");
            map.put(StatisticalReportEnum.GREEN_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PUBLIC_AREA.getField())) {
            //公建配套用房面积
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "all_area");
            map.put(StatisticalReportEnum.PUBLIC_AREA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.HOUSEHOLDS.getField())) {
            //住宅户数
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "housing_quantity");
            map.put(StatisticalReportEnum.HOUSEHOLDS.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.NUMBER.getField())) {
            //居住人数
            BigDecimal num = statisticalReportDao.getProjectArea(area, exportExcel, "number_residents");
            map.put(StatisticalReportEnum.NUMBER.getField(), num);
        }
    }

    /**
     * 查询黑名单数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getBlackListNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.BLACK_LIST.getField())) {
            //查询黑名单数量
            Integer num = statisticalReportDao.getBlackList(area, exportExcel);
            map.put(StatisticalReportEnum.BLACK_LIST.getField(), num);
        }
    }

    /**
     * 获取企业数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getCorpNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.CORP_NUM.getField())) {
            //查询企业数量
            Integer num = statisticalReportDao.getCorpNum(area, exportExcel);
            map.put(StatisticalReportEnum.CORP_NUM.getField(), num);
        }
    }

    /**
     * 获取项目数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getProjectNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.PROJECT_NUM.getField())) {
            //查询项目数量
            Integer num = statisticalReportDao.getProjectNum(area, exportExcel);
            map.put(StatisticalReportEnum.PROJECT_NUM.getField(), num);
        }
    }

    /**
     * 获取三体系认证数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getThreeSystem(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.THREE_SYSTEM.getField())) {
            // 通过三体系认证数量
            Integer num = statisticalReportDao.getThreeSystemNum(area, exportExcel, Common.ONE);
            map.put(StatisticalReportEnum.THREE_SYSTEM.getField(), num);
        }
    }

    /**
     * 未通过三体系认证数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getNoThreeSystem(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.NO_THREE_SYSTEM.getField())) {
            // 未通过三体系认证数量
            Integer num = statisticalReportDao.getThreeSystemNum(area, exportExcel, Common.ZERO);
            map.put(StatisticalReportEnum.NO_THREE_SYSTEM.getField(), num);
        }
    }

    /**
     * 成立党支部数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getOrganization(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.ORGANIZATION.getField())) {
            // 成立党支部数量
            Integer num = statisticalReportDao.getOrganizationNum(area, exportExcel, Common.ONE);
            map.put(StatisticalReportEnum.ORGANIZATION.getField(), num);
        }
    }

    /**
     * 未成立党支部数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getNoOrganization(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.NO_ORGANIZATION.getField())) {
            // 未成立党支部数量
            Integer num = statisticalReportDao.getOrganizationNum(area, exportExcel, Common.ZERO);
            map.put(StatisticalReportEnum.NO_ORGANIZATION.getField(), num);
        }
    }

    /**
     * 收入
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getIncome(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.MAIN_INCOME.getField())) {
            // 主营收入
            BigDecimal num = statisticalReportDao.getIncome(area, exportExcel, StatisticalReportEnum.MAIN_INCOME.getField());
            map.put(StatisticalReportEnum.MAIN_INCOME.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PUBLIC_INCOME.getField())) {
            // 公共收益
            BigDecimal num = statisticalReportDao.getIncome(area, exportExcel, StatisticalReportEnum.PUBLIC_INCOME.getField());
            map.put(StatisticalReportEnum.PUBLIC_INCOME.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PROFIT.getField())) {
            // 利润
            BigDecimal num = statisticalReportDao.getIncome(area, exportExcel, StatisticalReportEnum.PROFIT.getField());
            map.put(StatisticalReportEnum.PROFIT.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.OTHER_INCOME.getField())) {
            // 其他收入
            BigDecimal num = statisticalReportDao.getIncome(area, exportExcel, StatisticalReportEnum.OTHER_INCOME.getField());
            map.put(StatisticalReportEnum.OTHER_INCOME.getField(), num);
        }
    }

    /**
     * 人数
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getPersonNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        if (fields.contains(StatisticalReportEnum.CORP_ALL_PERSON_NUM.getField())) {
            // 企业总人数
            Integer num = statisticalReportDao.getCorpPersonNum(area, exportExcel, null);
            map.put(StatisticalReportEnum.CORP_ALL_PERSON_NUM.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PROJECT_ALL_PERSON_NUM.getField())) {
            // 项目总人数
            Integer num = statisticalReportDao.getProjectPersonNum(area, exportExcel, null);
            map.put(StatisticalReportEnum.PROJECT_ALL_PERSON_NUM.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.CORP_INSURANCE.getField())) {
            // 企业交五险一金人数
            Integer num = statisticalReportDao.getCorpPersonNum(area, exportExcel, StatisticalReportEnum.CORP_INSURANCE.getField());
            map.put(StatisticalReportEnum.CORP_INSURANCE.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PROJECT_INSURANCE.getField())) {
            // 项目交五险一金人数
            Integer num = statisticalReportDao.getProjectPersonNum(area, exportExcel, StatisticalReportEnum.PROJECT_INSURANCE.getField());
            map.put(StatisticalReportEnum.PROJECT_INSURANCE.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.CORP_CERTIFICATE.getField())) {
            // 企业持有相关中等从业资格证书的人数
            Integer num = statisticalReportDao.getCorpPersonNum(area, exportExcel, StatisticalReportEnum.CORP_CERTIFICATE.getField());
            map.put(StatisticalReportEnum.CORP_CERTIFICATE.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.PROJECT_CERTIFICATE.getField())) {
            // 项目持有相关中等从业资格证书的人数
            Integer num = statisticalReportDao.getProjectPersonNum(area, exportExcel, StatisticalReportEnum.PROJECT_CERTIFICATE.getField());
            map.put(StatisticalReportEnum.PROJECT_CERTIFICATE.getField(), num);
        }
    }

    /**
     * 查询各个等级的数量
     *
     * @param fields      参数集合
     * @param area        管辖地区
     * @param exportExcel 查询条件
     * @param map         map
     */
    private void getLevelNum(String fields, String area, ExportExcel exportExcel, Map<String, Object> map) {
        //获取最近设置的定时任务
        String time = scheduledTaskDao.getTime();
        //获取主管部门定义的年份
        String year = DateFormatUtil.getYear(time);
        if (fields.contains(StatisticalReportEnum.LEVEL_D.getField())) {
            // 查询D等级的数量
            Integer num = statisticalReportDao.getLevelNum(area, exportExcel, year, LevelEnum.D.getLevel());
            map.put(StatisticalReportEnum.LEVEL_D.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.LEVEL_A.getField())) {
            // 查询A等级的数量
            Integer num = statisticalReportDao.getLevelNum(area, exportExcel, year, LevelEnum.A.getLevel());
            map.put(StatisticalReportEnum.LEVEL_A.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.LEVEL_AA.getField())) {
            // 查询AA等级的数量
            Integer num = statisticalReportDao.getLevelNum(area, exportExcel, year, LevelEnum.AA.getLevel());
            map.put(StatisticalReportEnum.LEVEL_AA.getField(), num);
        }
        if (fields.contains(StatisticalReportEnum.LEVEL_AAA.getField())) {
            // 查询AAA等级的数量
            Integer num = statisticalReportDao.getLevelNum(area, exportExcel, year, LevelEnum.AAA.getLevel());
            map.put(StatisticalReportEnum.LEVEL_AAA.getField(), num);
        }
    }

    private void commonResult(ManagerPageResult mpr, JsonResult jr, List list, Integer num) {
        mpr.setCount(num);
        jr.setDs(list);
        mpr.setJson(jr);
    }

}
